%{
#include <string>
#include "Expression.h"
#include "Statement.h"
#include "Declaration.h"
#include "ExpressionStatement.h"
#include "CompoundStatement.h"
#include <vector>
#include "parser.hpp"
#define SAVE_TOKEN yylval.string = new std::string(yytext)
#define TOKEN(t) (yylval.token = t)
extern "C" int yywrap() { }

%}

%x COMMENT

%%

do		{
			return TOKEN(DO);
		}
for		{
			return TOKEN(FOR);
		}
while	{
			return TOKEN(WHILE);
		}
if		{
			return TOKEN(IF);
		}
else	{
			return TOKEN(ELSE);
		}		
		
char	{
			return(CHAR);
		}
		
short 	{
			return(SHORT);
		}
int		{
			return (INT);
		}
long	{
			return (LONG);
		}
float	{
			return(FLOAT);
		}
double	{
			return(DOUBLE);
		}	
		
		
"void main()" {
				return TOKEN(MAIN);
			} 

[0-9]+		{
				SAVE_TOKEN;
				return CONSTANT;
			}
[0-9]+\.[0-9]* {
					SAVE_TOKEN;
					return CONSTANT;
				}
				
				
"'"[a-zA-Z]"'"  {
					SAVE_TOKEN;
					return (STRING_LITERAL);
				}
[a-zA-Z_][a-zA-Z0-9_]* {
						SAVE_TOKEN;
						return IDENTIFIER; 
					 } 

"+="			{  return ADD_ASSIGN; }
"-="			{  return SUB_ASSIGN; }
"*="			{  return MUL_ASSIGN; }
"/="			{  return DIV_ASSIGN; }
"%="			{  return MOD_ASSIGN; }
"&="			{  return AND_ASSIGN; }
"^="			{  return XOR_ASSIGN; }
"|="			{  return OR_ASSIGN; }
"++"			{  return INC_OP; }
"--"			{  return DEC_OP; }
"&&"			{  return AND_OP; }
"||"			{  return OR_OP; }
"<="			{  return LE_OP; }
">="			{  return GE_OP; }
"=="			{  return EQ_OP; }
"!="			{  return NE_OP; }
";"			{  return(';'); }
("{"|"<%")		{  return('{'); }
("}"|"%>")		{  return('}'); }
","			{  return(','); }
":"			{  return(':'); }
"="			{  return('='); }
"("			{  return('('); }
")"			{  return(')'); }
("["|"<:")		{  return('['); }
("]"|":>")		{  return(']'); }
"."			{  return('.'); }
"&"			{  return('&'); }
"!"			{  return('!'); }
"~"			{  return('~'); }
"-"			{  return('-'); }
"+"			{  return('+'); }
"*"			{  return('*'); }
"/"			{  return('/'); }
"%"			{  return('%'); }
"<"			{  return('<'); }
">"			{  return('>'); }
"^"			{  return('^'); }
"|"			{  return('|'); }


[ \t\v\n\f] { /*ignore whitespaces*/ }
"/*"    { BEGIN(COMMENT); }
<COMMENT>"*/" {BEGIN(0); }
<COMMENT>[^"*/"]* {/*ignore comments*/  }
"//".*  { /*ignore comments*/  }
. {/*Ignore bad tokens*/}
